package com.ecut.xzh.service.impl;

import com.ecut.xzh.constant.MessageConstant;
import com.ecut.xzh.context.UserHolder;
import com.ecut.xzh.entity.VoucherOrder;
import com.ecut.xzh.exception.CustomException;
import com.ecut.xzh.mapper.VoucherMapper;
import com.ecut.xzh.mapper.VoucherOrderMapper;
import com.ecut.xzh.result.Result;
import com.ecut.xzh.service.VoucherService;
import com.ecut.xzh.utils.RedisIdWork;
import com.ecut.xzh.vo.VoucherVO;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;

/**
 * @author XZH
 */
@Service
public class VoucherServiceImpl implements VoucherService {

    @Resource
    private VoucherMapper voucherMapper;

    @Resource
    private VoucherOrderMapper voucherOrderMapper;

    @Resource
    private RedisIdWork redisIdWork;

    @Resource
    private RedissonClient redissonClient;

    /**
     * 获取优惠券信息
     *
     * @return
     */
    @Override
    public ArrayList<VoucherVO> getVoucher() {

        return voucherMapper.select();
    }

    /**
     * 抢购优惠券
     *
     * @param id
     */
    @Override
    public Result buyVoucher(Long id) {
        // 1.判断是否在抢购时间
        // 1.1根据id获取优惠券信息
        VoucherVO voucherVO = voucherMapper.getById(id);
        // 1.2秒杀未开始
        if (voucherVO.getBeginTime().isAfter(LocalDateTime.now())) {
            return Result.error(MessageConstant.KILL_NOT_BEGIN);
        }
        // 1.3秒杀结束
        if (voucherVO.getEndTime().isBefore(LocalDateTime.now())) {
            return Result.error(MessageConstant.KILL_IS_END);
        }

        // 2.判断库存是否充足
        // 2.1查询库存
        int stock = voucherMapper.count();
        // 2.2库存不足
        if (stock <= 0) {
            return Result.error(MessageConstant.KILL_STORE_EMPTY);
        }

        // 获取当前学生id
        Long studentId = UserHolder.getCurrentId();

        // 创建锁对象
        RLock lock = redissonClient.getLock("lock:order:" + studentId);

        // 获取锁
        boolean isLock = lock.tryLock();
        if (!isLock) {
            // 获取锁失败
            return Result.error(MessageConstant.CAN_NOT_REPEAT_ORDER);
        }

        try {
            //获取代理对象（事务）|（保证事务）
            VoucherService proxy = (VoucherService) AopContext.currentProxy();
            return proxy.createVoucherOrder(id);
        } finally {
            // 释放锁
            lock.unlock();
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Result<Long> createVoucherOrder(Long voucherId) {

        // 创建订单
        VoucherOrder voucherOrder = new VoucherOrder();
        // 学生id
        Long studentId = UserHolder.getCurrentId();
        voucherOrder.setStudentId(studentId);
        // 优惠券id
        voucherOrder.setVoucherId(voucherId);

        // 判断用户是否已经抢购过
        // 去优惠券订单表中查询用户是否已经抢购过
        int count = voucherOrderMapper.count(voucherOrder);
        if(count > 0){
            return Result.error(MessageConstant.ALREADY_BUY_VOUCHER);
        }
        // 扣减库存
        // 扣减库存
        Boolean success = voucherMapper.minusStore(voucherId);
        // 扣减失败
        if (!success) {
            return Result.error(MessageConstant.KILL_STORE_EMPTY);
        }

        // 插入用户抢购记录
        // 订单id
        long orderId = redisIdWork.nextId("order");
        voucherOrder.setId(orderId);

        // 插入订单
        voucherOrderMapper.insert(voucherOrder);

        // 返回优惠券订单id
        return Result.success(orderId);
    }
}
